package sardine.tpd;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultFileRegion;
import io.netty.handler.codec.http.*;
import io.netty.handler.stream.ChunkedStream;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import static io.netty.handler.codec.http.HttpHeaderUtil.isKeepAlive;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_0;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

/**
 * @auth bruce-sha
 * @date 2015/5/24
 */
public class StaticResourceHanlder {
    private static String staticFileFolder;
    private static String externalStaticFileFolder;

    public static void staticFileFolder(String staticFileFolder) {
        StaticResourceHanlder.staticFileFolder = staticFileFolder;
    }

    public static void externalStaticFileFolder(String externalStaticFileFolder) {
        StaticResourceHanlder.externalStaticFileFolder = externalStaticFileFolder;
    }

    public static boolean handleResource(FullHttpRequest request, ChannelHandlerContext ctx) {
        try {
            final String uri = request.uri();
            final QueryStringDecoder query = new QueryStringDecoder(uri);

            String path = query.path();

//            String fileName = path.substring(path.lastIndexOf('/') + 1);

            String mimeType = Mimes.getContentType(path);


            HttpResponse response = new DefaultHttpResponse(
                    request.protocolVersion() == HTTP_1_0 ? HTTP_1_0 : HTTP_1_1, OK);

//            response.headers().add("Access-Control-Allow-Origin", "*");
//            response.headers().add("Access-Control-Allow-Credentials", "true");

            response.headers().set(HttpHeaderNames.CONTENT_TYPE, mimeType);

            if (isKeepAlive(request)) response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);

//            Thread.currentThread().getContextClassLoader()


            boolean handled = false;

            if (!handled && staticFileFolder != null) {
                InputStream inputStream = null;

                ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
                String filePath = staticFileFolder + path.substring(1);

                URL url = classLoader.getResource(filePath);

                //考虑安全性 不允许显示目录内容

                if ("jar".equals(url.getProtocol())) {
                    URLConnection urlConnection = url.openConnection();
                    JarURLConnection jarUrlConnection = (JarURLConnection) urlConnection;
                    JarEntry jarEntry = jarUrlConnection.getJarEntry();
                    JarFile jarFile = jarUrlConnection.getJarFile();
                    // check if this is not a folder
                    // we can't rely on jarEntry.isDirectory() because of http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6233323
                    if (!jarEntry.isDirectory() && jarFile.getInputStream(jarEntry) != null) {
                        inputStream = urlConnection.getInputStream();
                    }
                }

                if ("file".equals(url.getProtocol())) {
                    final File file = new File(url.toURI());
                    if (file.exists() && file.isFile() && file.canRead())
                        inputStream = url.openConnection().getInputStream();
                }

                if (inputStream != null) {
                    response.headers().set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
                    {
                        //这个要缓存住
                        RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean();
                        long startTime = bean.getStartTime();
                        long expiresTime = startTime + 1000 * 24 * 60 * 60;

                        Date expiresDate = new Date();

                    }
                    ctx.write(response);
                    ctx.write(new ChunkedStream(inputStream), ctx.newProgressivePromise());

                    handled = true;
                }
            }

            if (!handled && externalStaticFileFolder != null) {
                File file = new File(externalStaticFileFolder + path);
                if (file.exists() && file.isFile() && file.canRead()) {
                    RandomAccessFile raf = new RandomAccessFile(file, "r");
                    long length = raf.length();
                    response.headers().setLong(HttpHeaderNames.CONTENT_LENGTH, length);
                    {
                        //缓存和过期时间设置
                        long lastModifiedTime = file.lastModified();

                        response.headers();

                    }
                    ctx.write(response);
                    ctx.write(new DefaultFileRegion(raf.getChannel(), 0, length), ctx.newProgressivePromise());
                    handled = true;
                }
            }

            if (!handled) return false;

            ChannelFuture lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);

            if (!isKeepAlive(request)) lastContentFuture.addListener(ChannelFutureListener.CLOSE);

        } catch (Exception ignore) {
//            e.printStackTrace();
            return false;
        }
        return true;
    }


}
